'''
dionysus - a web based dialogue management framework
Copyright (C) 2011  Eugeniu Costetchi <eugeniu.costetchi (at) tudor.lu>

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
'''

from DialogueManager.planning.PlanFragment import PlanFragment
from DialogueManager.planning.Action import *
from DialogueManager.planning.Operator import *
from DialogueManager.protocols.literals import *

def sort():
    pf = PlanFragment() + SayInteractionAction('You will be given some words. \
    I would like you to sort the words into groups, using one criterion at a time. \
    When you have finished sorting, I will ask you to name the group. Once these have \
    been done I would like you to sort words again, and again until you run out of\
    grouping criteria.')
    pf += _sort_out()
    
    return pf 

def _sort_out():
    pf = PlanFragment() + SayTemplateInteractionAction('These are the words for sorting: ${' + FREE_LISTING + '}')
    pf += SetVariableToContext('@ctx.variables.'+MAY_FINISH, False)
    pf += SetVariableToContext('@ctx.variables.'+TEMP_GROUP_LOW, [])
    pf += SetVariableToContext('@ctx.variables.'+TEMP_GROUP_TITLE, [])
    sequence = PlanFragment()
    sequence += _s1()
    sequence += _s2()
    sequence += _s3()
    pf = pf.add_while(Not(ValueOfVariable('@ctx.variables.'+MAY_FINISH)), sequence)
    return pf

def _s1():
    # asking and recording  group content in temp_group_low
    pf = PlanFragment() + SayInteractionAction('Please tell me which words can be sorted into one group?')
    pf += ListenInteractionAnction('@ctx.variables.'+TEMP_GROUP_LOW)
    
    seq = PlanFragment() + SayInteractionAction('Hm, a group should be at least two words, please try again')
    seq += ListenInteractionAnction('@ctx.variables.'+TEMP_GROUP_LOW)
    
    pf = pf.add_while(And(Not(IsInputType(InputTypes.NONE)), LessThan(Length('@ctx.variables.'+TEMP_GROUP_LOW), 2)),
                      seq)
    
    pf = pf.add_condition(IsInputType(InputTypes.NONE),
                          PlanFragment() + SetVariableToContext('@ctx.variables.'+MAY_FINISH, True))
    return pf

def _s2():
    #asking and recording group title in temp_group_title
    then = PlanFragment() + SayInteractionAction('What name or title would you give to the group above?')
    then += ListenInteractionAnction('@ctx.variables.'+TEMP_GROUP_TITLE)
    
    seq = PlanFragment() + SayInteractionAction('The group title is just one word, can you please provide a group title?')
    seq += ListenInteractionAnction('@ctx.variables.'+TEMP_GROUP_TITLE)
    then = then.add_while(And(Not(IsInputType(InputTypes.NONE)), Not(IsInputType(InputTypes.SINGLE))), seq)
    then = then.add_condition(IsInputType(InputTypes.NONE), PlanFragment() + [SayTemplateInteractionAction('I will not consider [ ${temp_group_title} ] as a group because I miss the title'),
                                                                            SetVariableToContext('@ctx.variables.'+MAY_FINISH, True)])
    return PlanFragment().add_condition(Not(ValueOfVariable('@ctx.variables.'+MAY_FINISH)), then)

def _s3():
    #recording the tranzaction
    then_fragment = PlanFragment() + UpdateDictInContext('@ctx.variables.groups',
                                         '@ctx.variables.'+TEMP_GROUP_TITLE,
                                         '@ctx.variables.'+TEMP_GROUP_LOW)
    else_fragment = PlanFragment() + SayTemplateInteractionAction('${name}, it seems that you \
            had difficulties in grouping, would you like to continue grouping?')
    else_fragment += ListenInteractionAnction()
    
    seq = PlanFragment() + SayInteractionAction('What do you mean? Please say *yes*\
                                                 to continue grouping or *no* to stop grouping.')
    seq += ListenInteractionAnction()
    else_fragment = else_fragment.add_while(And(Not(IsInputType(InputTypes.NONE)), Not(IsInputType(InputTypes.YN))), seq)
    else_fragment = else_fragment.add_condition(IsAnswerAffirmative(), PlanFragment() + SetVariableToContext('@ctx.variables.'+MAY_FINISH, False))
    #TODO remove value of variable operator from not, which should recognize the variable link, like any other operator
    return PlanFragment().add_condition(Not(ValueOfVariable('@ctx.variables.'+MAY_FINISH)), then_fragment, else_fragment)

